#!/usr/bin/python -O

import os, sys, re

from qpid.messaging import Connection, Message, MessagingError

from amqp import RoutingKey
from protomsg import ProtoMsg

def get_msg(conn, rx_binding, output, msg_handler=None):

    session = conn.session()
    receiver = session.receiver(address)

    while True:
        message = receiver.fetch()
        session.acknowledge(sync=False)

        if message.content_type == 'application/x-protobuf':
            sKey = message.properties.get('x-amqp-0-10.routing-key', None)
            print 'Got {Message : %s}' % sKey

            if sKey and rx_binding.match(sKey):
                rKey = RoutingKey(sKey)

                pMsg = ProtoMsg(opts.protoSrc,
                                rKey.package, rKey.publication)
                pMsg.parse_from_string(message.content)

                if __debug__:
                    output.write('%s\n' % pMsg)
                    output.flush()

                if msg_handler:
                    msg_handler(message)
        else:
            print 'Not a google protobuf message'

# ---- main -----
from optparse import OptionParser

parser = OptionParser()
parser.add_option('--sub-ip', dest = 'sub_ip',
      action='store', default = '127.0.0.1',
      help='ip of the broker to subscribe, default [%default]')
parser.add_option('--sub-port', dest = 'sub_port',
      action='store', type = int, default = 5672,
      help='port of the broker to subscribe, default [%default]')
parser.add_option('--pub-ip', dest = 'pub_ip',
      action='store', default = '127.0.0.1',
      help='ip of the broker to publish, default [%default]')
parser.add_option('--pub-port', dest = 'pub_port',
      action='store', type = int, default = 5672,
      help='port of the broker to publish, default [%default]')
parser.add_option('--proto-src', dest ='protoSrc',
      action='store', default = os.path.join(os.environ['HOME'], 'protos'),
      help='directory to store subscribe, default [%default]')
parser.add_option('--binding-key', dest = 'bindingKeys', 
      action='append')
parser.add_option('--output-file', dest ='out',
      action='store', default = sys.stdout,
      help='file to dump message text, default [stdout]')

(opts, args) = parser.parse_args()

if opts.bindingKeys is None:
    opts.bindingKeys = ['#']

address = 'amq.topic'
sub_broker = '%s:%d' % (opts.sub_ip, opts.sub_port)
pub_broker = '%s:%d' % (opts.pub_ip, opts.pub_port)

sub_conn = Connection(sub_broker)
pub_conn = Connection(pub_broker)

try:
    sub_conn.open()
    rx_binding = re.compile('|'.join(k.replace('.', '\.').replace('#', '.*')
                                     for k in opts.bindingKeys))
    if opts.out == sys.stdout:
        output = sys.stdout
    else:
        output = open(opts.out, 'w')


    try:
        pub_conn.open()
        pub_session = pub_conn.session()
        sender = pub_session.sender(address)

        try:
            get_msg(sub_conn, rx_binding, output, sender.send)

        except KeyboardInterrupt:
            print 'Control-C pressed, exiting...'

        finally:
            pub_conn.close()

    except MessagingError, e:
        print 'Failed connecting to publish broker'
        sys.exit(2)

    finally:
        if output != sys.stdout:
            output.close()
        sub_conn.close()

except MessagingError, e:
    print 'Failed connecting to subscribe broker'
    sys.exit(1)
